"""
使用 cProfile 进行性能分析

运行分析:
python cprofile_test.py
python -m cProfile -s cumtime cprofile_test.py
"""

import cProfile
import pstats
import io
from string_permutation import (
    permute_recursive,
    permute_iterative,
    permute_lexicographic,
    permute_heap,
    permute_generator
)


class ProfileAnalyzer:
    """性能分析器"""
    
    def __init__(self):
        self.algorithms = {
            "递归方法": permute_recursive,
            "迭代方法": permute_iterative,
            "字典序法": permute_lexicographic,
            "Heap算法": permute_heap,
            "生成器法": lambda s: list(permute_generator(s))
        }
    
    def profile_algorithm(self, algo_name, algo_func, test_string, iterations=10):
        """分析单个算法的性能"""
        print(f"\n🔍 分析 {algo_name}")
        print("-" * 50)
        
        # 创建性能分析器
        profiler = cProfile.Profile()
        
        # 运行算法并进行分析
        profiler.enable()
        for _ in range(iterations):
            result = algo_func(test_string)
        profiler.disable()
        
        # 获取分析结果
        s = io.StringIO()
        ps = pstats.Stats(profiler, stream=s)
        ps.sort_stats('cumulative')
        ps.print_stats(20)  # 显示前20个最耗时的函数
        
        profile_output = s.getvalue()
        
        # 解析关键统计信息
        lines = profile_output.split('\n')
        stats_line = None
        for line in lines:
            if 'function calls' in line:
                stats_line = line.strip()
                break
        
        print(f"算法: {algo_name}")
        print(f"测试字符串: '{test_string}' x {iterations} 次")
        print(f"结果数量: {len(result)} 个排列")
        if stats_line:
            print(f"统计信息: {stats_line}")
        
        print("\n📊 性能热点 (前10个):")
        print("-" * 70)
        print(f"{'累计时间':>10} {'每次调用':>10} {'调用次数':>8} {'函数名':<30}")
        print("-" * 70)
        
        # 解析和显示前10个最耗时的函数
        in_stats = False
        count = 0
        for line in lines:
            if 'cumulative' in line or 'cumtime' in line:
                in_stats = True
                continue
            if in_stats and line.strip() and count < 10:
                parts = line.strip().split()
                if len(parts) >= 6:
                    try:
                        ncalls = parts[0]
                        tottime = parts[1]
                        cumtime = parts[3]
                        percall = parts[4] if len(parts) > 4 else "0"
                        filename_func = ' '.join(parts[5:])
                        
                        # 提取函数名
                        if ':' in filename_func:
                            func_name = filename_func.split(':')[-1]
                        else:
                            func_name = filename_func
                        
                        print(f"{cumtime:>10} {percall:>10} {ncalls:>8} {func_name:<30}")
                        count += 1
                    except (ValueError, IndexError):
                        continue
        
        return profiler, profile_output
    
    def compare_algorithms(self, test_string="abcd", iterations=5):
        """比较所有算法的性能"""
        print("⚙️  cProfile 性能分析比较")
        print("=" * 80)
        print(f"测试配置: 字符串 '{test_string}', 每个算法运行 {iterations} 次")
        print("=" * 80)
        
        results = {}
        
        for algo_name, algo_func in self.algorithms.items():
            try:
                profiler, output = self.profile_algorithm(
                    algo_name, algo_func, test_string, iterations
                )
                results[algo_name] = {
                    'profiler': profiler,
                    'output': output
                }
                print()
                
            except Exception as e:
                print(f"❌ {algo_name} 分析失败: {e}")
                results[algo_name] = None
        
        return results
    
    def detailed_recursive_analysis(self):
        """递归算法的详细分析"""
        print("\n🔬 递归算法详细分析")
        print("=" * 60)
        
        test_string = "abcd"
        profiler = cProfile.Profile()
        
        print(f"分析递归算法处理 '{test_string}' 的详细调用栈...")
        
        profiler.enable()
        result = permute_recursive(test_string)
        profiler.disable()
        
        print(f"✅ 生成了 {len(result)} 个排列")
        
        # 详细的统计信息
        s = io.StringIO()
        ps = pstats.Stats(profiler, stream=s)
        ps.sort_stats('cumulative')
        ps.print_stats()
        
        output = s.getvalue()
        print("\n📈 完整的函数调用分析:")
        print("-" * 60)
        
        # 只显示与我们的算法相关的函数
        lines = output.split('\n')
        in_stats = False
        for line in lines:
            if 'cumulative' in line or 'cumtime' in line:
                in_stats = True
                print(line)
                continue
            if in_stats and line.strip():
                if ('permute' in line.lower() or 
                    'string_permutation' in line or
                    '<method' in line):
                    print(line)
        
        return profiler
    
    def save_profile_results(self, test_string="abcd"):
        """保存性能分析结果到文件"""
        print(f"\n💾 保存性能分析结果")
        print("-" * 40)
        
        for algo_name, algo_func in self.algorithms.items():
            try:
                filename = f"profile_{algo_name.replace(' ', '_').lower()}.prof"
                
                profiler = cProfile.Profile()
                profiler.enable()
                result = algo_func(test_string)
                profiler.disable()
                
                # 保存二进制格式的分析结果
                profiler.dump_stats(filename)
                
                # 生成文本格式的报告
                with open(f"{filename}.txt", 'w', encoding='utf-8') as f:
                    s = io.StringIO()
                    ps = pstats.Stats(profiler, stream=s)
                    ps.sort_stats('cumulative')
                    ps.print_stats()
                    f.write(s.getvalue())
                
                print(f"✅ {algo_name}: {filename} & {filename}.txt")
                
            except Exception as e:
                print(f"❌ {algo_name} 保存失败: {e}")
        
        print("\n💡 使用方法:")
        print("# 查看二进制分析文件:")
        print("python -m pstats profile_递归方法.prof")
        print("# 在 pstats 交互环境中:")
        print("% sort cumulative")
        print("% stats 10")


def run_cprofile_tests():
    """运行 cProfile 测试套件"""
    analyzer = ProfileAnalyzer()
    
    # 基本算法比较
    comparison_results = analyzer.compare_algorithms("abcd", iterations=3)
    
    # 递归算法详细分析
    recursive_analysis = analyzer.detailed_recursive_analysis()
    
    # 保存分析结果
    analyzer.save_profile_results("abcd")
    
    print("\n" + "=" * 80)
    print("🎯 cProfile 性能分析完成!")
    print("=" * 80)
    print("\n🔍 分析要点:")
    print("- cProfile 提供了函数级别的详细性能分析")
    print("- 可以识别性能瓶颈和热点函数")
    print("- 显示函数调用次数和累计时间")
    print("- 递归算法会显示大量的递归调用开销")
    print("- 分析结果已保存到 .prof 和 .txt 文件")
    
    print("\n📊 后续分析建议:")
    print("1. 使用 snakeviz 可视化分析结果:")
    print("   pip install snakeviz")
    print("   snakeviz profile_递归方法.prof")
    print("2. 使用 py-spy 进行实时性能分析:")
    print("   pip install py-spy")
    print("   py-spy record -o profile.svg -- python your_script.py")


if __name__ == "__main__":
    run_cprofile_tests()
